﻿using System;
using System.Web.UI;
using BigfootWeb;

namespace BigfootDNN.Mvc
{

    /// <summary>
    /// This is the base class of the RouteUserControl. In a purely MVC application it is the only registered DNN 
    /// control and handles all the MVC requests for the module. It uses the URL route parameter to identify the proper
    /// controller and action to execute
    /// </summary>
    public abstract class BaseRouteUserControl : DotNetNuke.Entities.Modules.PortalModuleBase
    {

        /// <summary>
        /// This funciton must be overridden by the inheritor in order to Init the MVC application object
        /// </summary>
        public abstract DnnApp InitApp();

        /// <summary>
        /// Holds the current route information
        /// </summary>
        public RouteInfo Route;

        /// <summary>
        /// Holds a reference to the application class created for this instance of the module
        /// </summary>
        public DnnApp App;

        // Initialize the route control
        protected void Page_Init(object sender, EventArgs e)
        {
            // Init the MVC app
            App = InitApp();

            try
            {
                // Get the current route request
                var paramName = Params.QS.Route(ModuleId);
                var routeData = App.Values.GetValue(paramName);
                Route = string.IsNullOrEmpty(routeData)
                                ? new RouteInfo("Home", "Index", ModuleConfiguration, App)
                                : App.DecodeUrlRoute(routeData);
                Route.User = UserInfo;
                Route.App = App;

                // Execute the action
                var result = RouteHelper.ExecuteAction(Route);
                
                // Process the result
                ProcessResult(result);
            }
            catch (Exception ex)
            {
                App.HandleException(ex, false);
                LoadErrorView(ex);
            }

        }

        private Control GetRouteContent()
        {
            return FindControl("RouteContent");
        }

        private void ProcessResult(ActionResult result)
        {
            switch (result.Type)
            {
                case ActionResult.ActionTypeEnum.View:
                    var contentHolder = GetRouteContent();
                    contentHolder.Controls.Add(DnnApp.LoadView(result.Route.ViewPath, result.Data, this.Page, "Route", result.Route));
                    break;

                case ActionResult.ActionTypeEnum.Literal:
                    result.Route.App.RenderLiteral(result.Data.ToString());
                    break;

                case ActionResult.ActionTypeEnum.Json:
                    result.Route.App.RenderJson(result.Data.ToString());
                    break;
            }
        }

        private void LoadErrorView(Exception ex)
        {
            // Load the error view
            try
            {
                var returnUrl = "";
                if (Route != null) returnUrl = Route.GetMvcUrl();
                object data = ErrorViewModel.Create(ex, returnUrl);
                GetRouteContent().Controls.Add(DnnApp.LoadView(App.ErrorViewPath, data, this.Page));
            }
            catch (Exception)
            {
                Response.Write(ex.ToString());
            }
            
        }


        /// <summary>
        /// Gets the form name. Can be used by jquery (includes the pre #)
        /// </summary>
        public string FormName()
        {
            if (Page.Form != null)
            {
                return "#" + Page.Form.ClientID;
            }
            else
            {
                return "#Form";
            }
        }

    }


}
